import Cesium, { Cartesian3, LabelCollection, Rectangle } from '../Ces/Cesium';
import WeVectorObjectRender from './WeVectorObjectRender';
import OLMvt from '../Module/VectorTile/OLMvt';
import WeLabelProxy from './WeLabelProxy';

function isChinese(str: string): boolean {
    const reg = /^[\u4E00-\u9FA5\uF900-\uFA2D]+$/;
    return reg.test(str);
}

class WeVectorMvtLabelRender extends WeVectorObjectRender {
    url: string;
    styles: { [key: string]: any };
    format: any;
    _rectangleScratch: Rectangle;

    constructor(options: any) {
        super(options);
        this.url = options.url;
        this.styles = {};
        this.format = OLMvt.get();
        this._rectangleScratch = new Cesium.Rectangle();
    }

    getStyleContent(element: any, level: number, fontAltas: any, extent: number[], rectangle: Rectangle): { style: any; text: string; position: Cartesian3 } | undefined {
        const myStyles = this.styles;
        const geometryType = element.getType();
        const layer = element.get('layer');
        let text = element.get('_name_zh_s');

        if (!text) {
            text = element.get('_name');
        }

        if (!layer || !text || text === '' || !isChinese(text)) {
            return undefined;
        }

        if (fontAltas && !fontAltas.validCache(text)) {
            return undefined;
        }

        if (geometryType === 'Point') {
            const vars = layer.split(' ');
            const var1 = vars[0];

            if (level < 4 && var1 === 'City') {
                return undefined;
            }

            if (var1 === 'City' || layer.endsWith('/label')) {
                if (!myStyles[layer]) {
                    if (var1 === 'Water'/** || var1 === 'Ocean' */) {
                        myStyles[layer] = {
                            fillColor: Cesium.Color.fromCssColorString('#6666D8'),
                            outlineColor: Cesium.Color.WHITE,
                            outlineWidth: 0.2,
                            scale: 0.8,
                        };
                    } else if (layer === 'Admin0 forest or park/label') {
                        myStyles[layer] = {
                            fillColor: Cesium.Color.fromCssColorString('#587045'),
                            outlineColor: Cesium.Color.WHITE,
                            outlineWidth: 0.8,
                            scale: 0.8,
                        };
                    } else {
                        // console.info(layer);
                        // myStyles[layer] = {
                        //   fillColor: Cesium.Color.fromRandom({
                        //     minimumRed: 0.75,
                        //     minimumGreen: 0.75,
                        //     minimumBlue: 0.75,
                        //     alpha: 1.0,
                        //   }),
                        // };
                    }
                }
            }
        } else if (geometryType === 'MultiLineString' || geometryType === 'LineString') {
            if (layer!== 'Graticule/label'
                && layer!== 'Water line small scale/label'
                && layer!== 'Water line medium scale/label'
                && layer!== 'Landform/label' && layer.endsWith('/label')) {
                if (layer === 'Road/label'
                    || layer === 'Railroad/label'
                    || layer === 'Trail or path/label'
                    || layer === 'Road tunnel/label') {
                    myStyles[layer] = {
                        outlineColor: Cesium.Color.BLACK,
                        fillColor: Cesium.Color.WHITE,
                        outlineWidth: 2,
                        scale: 0.7,
                    };
                } else if (layer === 'Water area/label'
                    || layer === 'Water line large scale/label'
                    || layer === 'Water line/label'
                    || layer === 'Water line large scale/label'
                    || layer === 'Water area large scale/label'
                    || layer === 'Ferry/label') {
                    myStyles[layer] = {
                        fillColor: Cesium.Color.fromCssColorString('#6666D8'),
                        outlineColor: Cesium.Color.WHITE,
                        outlineWidth: 0.2,
                        scale: 0.8,
                    };
                } else {
                    // console.info(layer);
                }

                const arr = element.flatCoordinates_;
                const middleIndex = Math.floor(arr.length / 2);
                const deleteCount = arr.length - 2;

                arr.splice(middleIndex + 2, deleteCount);
                arr.splice(0, middleIndex);
            }
        }

        const style = myStyles[layer];

        if (!style) {
            return undefined;
        }

        const flatCoordinates = element.getGeometry().getFlatCoordinates();

        const longitude = rectangle.west + rectangle.width * flatCoordinates[0] / extent[2];
        const latitude = rectangle.north - rectangle.height * flatCoordinates[1] / extent[3];
        const position = Cesium.Cartesian3.fromRadians(longitude, latitude);

        return {
            style,
            text,
            position,
        };
    }

    // 请求图片的方法及类型注解
    requestImage(x: number, y: number, level: number, _request: any, imageryLayerProvider: any): Promise<{ renderObj: WeLabelProxy | LabelCollection } | {}> {
        const url = `${imageryLayerProvider.url}/${level}/${y}/${x}`;
        const that = this;
        const tilingScheme = imageryLayerProvider.tilingScheme;
        const fontAltas = this._fontAltas;

        return new Promise((resolve) => {
            Cesium.Resource.fetchArrayBuffer(url).then((geojson: ArrayBuffer) => {
                const rectangle = tilingScheme.tileXYToRectangle(x, y, level, that._rectangleScratch);
                const { features, extent } = that.format.readFeatures(geojson);

                // const labelCollection = fontAltas? this._fontAltas.NewLabelCollection() : new Cesium.LabelCollection();
                const labelCollection = new WeLabelProxy(this._altasLabelCollection);
                features.forEach((element: any) => {
                    const styleContent = that.getStyleContent(element, level, fontAltas, extent, rectangle);

                    if (styleContent) {
                        const options = styleContent.style;
                        const { text, position } = styleContent;
                        const font = `bold 32px ${that._font}`;
                        const style = Cesium.LabelStyle.FILL_AND_OUTLINE;
                        const horizontalOrigin = Cesium.HorizontalOrigin.CENTER;

                        labelCollection.add({
                            font,
                            style,
                            horizontalOrigin,
                            text,
                            position,
                           ...options,
                        });
                    }
                });
                if (labelCollection.length === 0) {
                    labelCollection.destroy();
                    resolve({});
                } else {
                    resolve({ renderObj: labelCollection });
                }
            }).catch(() => {
                resolve({});
            });
        });
    }
}

export default WeVectorMvtLabelRender;
